<?php

namespace App\Services\SwitchPay;

use App\Caches\AliH5PayCreateCache;
use App\Commons\CommonConstant;
use App\Models\Orders;
use App\Services\PayMchService;
use Illuminate\Http\Request;

require_once base_path('extend/alipay/wappay/service/AlipayTradeService.php');
require_once base_path('extend/alipay/wappay/buildermodel/AlipayTradeWapPayContentBuilder.php');

/**
 * 阿里网页支付
 * 接入文档: https://docs.open.alipay.com/60/104790/
 */
class AlipayH5 extends SwitchPayBase
{
    protected $payConfig;

    function __construct($pay_platform, $game_id, $game_channel_id)
    {
        parent::__construct($pay_platform, $game_id, $game_channel_id);

        $alipay_name = $this->gameChannel['alih5_pay'];
        $config = PayMchService::getInstance()->getByName($alipay_name);
        $config2 = CommonConstant::ALIPAY_CONFIG_LIST[$alipay_name];
        $this->payConfig = array_merge($config, $config2);
        $this->payConfig['notify_url'] = $this->callbackUrl();
    }

    private function getAliH5PayUrl($order)
    {
        $trade_no = $order->trade_no;
        $host = $this->payConfig['host'] ?? config('app.url');
        $url = "{$host}/alipay_h5?trade_no={$trade_no}";
        return $url;
    }

    // 支付结果页面url
    public function payRedirectUrl(Orders $order, $params = [])
    {
        $url = $params['now_url'] ?? '';
        if (empty($url)) {
            $host = $this->payConfig['host'] ?? config('app.url');
            $url = "{$host}/switch_pay/info/{$order->trade_no}";
        }

        return $url;
    }

    public function payInit(Orders $order, Request $request)
    {
        $params = $request->input();
        $trade_no = $order->trade_no;
        $cache = AliH5PayCreateCache::getInstance()->get($trade_no);
        if (!empty($cache)) {
            return yqok($cache);
        }

        $money = $order->money;
        $body  = $order->goods_name;

        $timeout_express   = "1m";
        $payRequestBuilder = new \AlipayTradeWapPayContentBuilder();
        $payRequestBuilder->setBody($body);
        $payRequestBuilder->setSubject($body);
        $payRequestBuilder->setOutTradeNo($order->trade_no);
        $payRequestBuilder->setTotalAmount($money);
        $payRequestBuilder->setTimeExpress($timeout_express);

        $return_url = $this->payRedirectUrl($order, $params);
        $payResponse = new \AlipayTradeService($this->payConfig);
        $result = $payResponse->wapPay($payRequestBuilder, $return_url, $this->payConfig['notify_url']);

        $data = [
            'pay_form' => $result,
            'message'  => $this->getAliH5PayUrl($order)
        ];

        // if ($order->user_id == 10480164) {
        //     $result = $payResponse->wapPay($payRequestBuilder, $return_url, $this->payConfig['notify_url'], true, 'get');
        //     $appid = $this->payConfig['app_id'];
        //     $data['message'] = "alipays://platformapi/startapp?appId={$appid}&url=" . $this->getAliH5PayUrl($order);
        // }

        AliH5PayCreateCache::getInstance()->update($trade_no, $data);

        // 如果是扫码支付
        $is_qrcode_pay = $request->input('qrcode_pay') ?? 0;
        if ($is_qrcode_pay == 1) {
            $jump_qrcode_url = $this->getAliH5PayUrl($order);
            return yqok([
                'jump_qrcode_url' => $jump_qrcode_url,
            ]);
        }

        return yqok($data);
    }

    /**
     * 处理充值回调
     * @param Request $request 请求参数
     * @param string  $cb_type 谁回调过来 server,client
     * @return void|string      返回第三方订单
     */
    public function payCb(Request $request, $cb_type)
    {
        $notify = $this->payNotify;

        $params       = $request->all();
        $alipaySevice = new \AlipayTradeService($this->payConfig);
        $result       = $alipaySevice->check($params);

        /* 实际验证过程建议商户添加以下校验。
        1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号，
        2、判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额），
        3、校验通知中的seller_id（或者seller_email) 是否为out_trade_no这笔单据的对应的操作方（有的时候，一个商户可能有多个seller_id/seller_email）
        4、验证app_id是否为该商户本身。
         */
        if (!$result) {
            $notify->errno = 90048;
            return $notify;
        }

        //是否支付成功
        if ($cb_type == 'server' && $params['trade_status'] != 'TRADE_SUCCESS') {
            $notify->errno = 90047;
            return $notify;
        }

        //商户订单号
        $trade_no = htmlspecialchars($params['out_trade_no']);
        $order    = Orders::where('trade_no', $trade_no)->first();
        if (!$order) {
            $notify->errno = 3;
            return $notify;
        }

        // 校验充值金额
        if (abs($order->money - $params['total_amount']) > 1) {
            $notify->errno = 99;
            return $notify;
        }

        $notify->order          = $order;
        $notify->tradeNo        = $trade_no;
        $notify->channelTradeNo = htmlspecialchars($params['trade_no']);
        $notify->mchId          = $this->payConfig['mch_id'];

        return $notify;
    }

    // 失败返回
    public function payErr()
    {
        return 'fail';
    }

    // 成功返回
    public function payOk()
    {
        return 'success';
    }
}
